package ie.timalb.chess.main.core.grid;

import java.util.Iterator;
import sun.reflect.generics.reflectiveObjects.NotImplementedException;

public class CellIterator implements Iterator<Cell> {
	private Cells cells;
	private Cell currentCell;
	private CellIteratorStrategy strategy;

	public CellIterator(Cells cells, CellIteratorStrategy strategy) {		
		super();
		setCells(cells);
		setStrategy(strategy);
	}

	@Override
	public boolean hasNext() {
		if (getNext()!=null){
			return true;
		}else{
			return false;	
		}		
	}

	@Override
	public Cell next() {
		Cell tmp = getNext();
		
		if (tmp!=null){
			setCurrentCell(tmp);
			return getCurrentCell();
		}else{			
			return null;
		}
	}
	
	private Cell getNext() {
		Cell next = null;
		if (getCurrentCell() == null)
		{			
			next = getStrategy().getFirstCell();
		}else if (areWeOnTheEndOfTheIteration()){
			return null;
		}else{
			next = getStrategy().getNextCell(getCurrentCell());										
		}
		
		if (getCells().contains(next)){
			return (next);	
		}else{
			next = getStrategy().onNextOutOfRange (getCurrentCell());
			if (getCells().contains(next)){
				return (next);
			}else{
				return null;	
			}			 
		}
	}
	
	private boolean areWeOnTheEndOfTheIteration (){
		return getCurrentCell().equals(getStrategy().getLastCell());		
	}

	@Override
	public void remove() {
		throw new NotImplementedException();
	}
	
	private Cells getCells() {
		return this.cells;
	}

	private void setCells(Cells cells) {
		this.cells = cells;
	}

	private Cell getCurrentCell() {
		return this.currentCell;
	}

	private void setCurrentCell(Cell cell) {
		this.currentCell = cell;
	}

	private CellIteratorStrategy getStrategy() {
		return strategy;
	}

	private void setStrategy(CellIteratorStrategy strategy) {
		this.strategy = strategy;
	}	
}
